package com.autonavi.yunda.yunji.core.vo.response;

import com.autonavi.yunda.yunji.common.utils.JsonUtils;
import com.autonavi.yunda.yunji.core.enums.ComponentSourceType;
import com.autonavi.yunda.yunji.core.enums.ComponentType;
import com.autonavi.yunda.yunji.core.enums.PartUnitInterfaceStatus;
import com.autonavi.yunda.yunji.core.model.dto.PartUnitDTO;
import com.autonavi.yunda.yunji.core.model.vo.ComponentData;
import com.autonavi.yunda.yunji.core.model.vo.PartUnitExtraData;
import com.autonavi.yunda.yunji.core.service.thirdpartyservice.vo.TagVO;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.util.DigestUtils;

import java.sql.Timestamp;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static com.autonavi.yunda.yunji.core.model.constants.PartUnitConstants.VERSION_DEFAULT;

@Data
public class PartUnitVO {
    private Long id;
    private ComponentType type;
    private PartUnitInterfaceStatus status;
    private String code;
    private String version;
    private String title;
    private String falconId;
    private String yuncangId;
    private List<TagVO> tags;
    private List<ComponentData> unitList;
    private List<ComponentData> partList;
    private ComponentSourceType sourceType;
    private Long sourceId;
    private String createUser;
    private String updateUser;
    private Timestamp createTime;
    private Timestamp updateTime;
    private PartUnitExtraData extraData;
    private List<Long> tagIds;
    private String approvalFlowUrl;
    private String shelfApprovalFlowUrl;

    public static PartUnitVO from(PartUnitDTO dto, String approvalFlowUrl) {
        PartUnitVO vo = from(dto);
        if (StringUtils.isNotBlank(dto.getExtraData().getTestBPMSFlowId())) {
            vo.setApprovalFlowUrl(String.format(approvalFlowUrl, vo.getExtraData().getTestBPMSFlowId()));
        }
        if (StringUtils.isNotBlank(dto.getExtraData().getShelfProcInstId())) {
            vo.setShelfApprovalFlowUrl(String.format(approvalFlowUrl, vo.getExtraData().getShelfProcInstId()));
        }
        return vo;
    }

    public static PartUnitVO from(PartUnitDTO dto) {
        PartUnitVO vo = new PartUnitVO();
        BeanUtils.copyProperties(dto, vo);
        return vo;
    }

    public PartUnitDTO toAddDto(Map<Long, TagVO> tagIdMap, String operatorId) {
        PartUnitDTO dto = new PartUnitDTO();
        dto.setType(type);
        dto.setTags(generateTags(tagIdMap));
        dto.setVersion(VERSION_DEFAULT);
        dto.setTitle(title);
        dto.setStatus(PartUnitInterfaceStatus.INIT);
        dto.setFalconId(falconId);
        dto.setPartList(partList);
        dto.setUnitList(unitList);
        dto.setCode(DigestUtils.md5DigestAsHex(UUID.randomUUID().toString().getBytes()));
        dto.setCreateUser(operatorId);
        dto.setUpdateUser(operatorId);
        return dto;
    }

    public UpdateWrapper<PartUnitDTO> toUpdateWrapper(Map<Long, TagVO> tagIdMap, String empId) {
        UpdateWrapper<PartUnitDTO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        updateWrapper.set("status", PartUnitInterfaceStatus.INIT);
        if (type != null) {
            updateWrapper.set("type", type);
        }
        if (Strings.isNotBlank(title)) {
            updateWrapper.set("title", title);
        }
        if (Strings.isNotBlank(empId)) {
            updateWrapper.set("update_user", empId);
        }
        if (tagIdMap != null) {
            updateWrapper.set("tags", JsonUtils.toString(generateTags(tagIdMap)));
        }
        if (partList != null) {
            updateWrapper.set("part_list", JsonUtils.toString(partList));
        }
        if (unitList != null) {
            updateWrapper.set("unit_list", JsonUtils.toString(unitList));
        }
        return updateWrapper;
    }

    private List<TagVO> generateTags(Map<Long, TagVO> tagIdMap) {
        List<TagVO> list = new LinkedList<>();
        tagIds.forEach(tagId -> {
            if (tagIdMap.containsKey(tagId)) {
                list.add(tagIdMap.get(tagId));
            }
        });
        return list;
    }

    public boolean addValidate() {
        return type != null && Strings.isNotBlank(falconId);
    }

}
